package com.bls.auth.basic; import org.mindrot.jbcrypt.BCrypt; import com.bls.core.user.User; import com.bls.dao.UserDao; import com.google.common.base.Optional; import io.dropwizard.auth.AuthenticationException; import io.dropwizard.auth.Authenticator; import io.dropwizard.auth.basic.BasicCredentials; import io.dropwizard.hibernate.UnitOfWork; import static com.bls.AugmentedConfiguration.PW_HASH_SECURITY_LEVEL; import static com.google.common.base.Preconditions.checkState; /** * Basic Authenticator class using plaintext credentials * Used to authenticate resources with @Auth annotation * * @param K entity key type for User */ public class BasicAuthenticator implements Authenticator<BasicCredentials, User> { private final UserDao<User> userDao; public BasicAuthenticator(UserDao<User> userDao) {this.userDao = userDao;} public static String generateSafeHash(final String plaintextPassword) { return BCrypt.hashpw(plaintextPassword, BCrypt.gensalt(PW_HASH_SECURITY_LEVEL)); } private static boolean isMatched(final String plaintextPassword, final String hashed) { return BCrypt.checkpw(plaintextPassword, hashed); } @UnitOfWork public Optional<User> authenticate(final BasicCredentials basicCredentials) throws AuthenticationException { String email = basicCredentials.getUsername(); String plaintextPassword = basicCredentials.getPassword(); final Optional<User> user = userDao.findByEmail(email); if (user.isPresent()) { final User existingUser = user.get(); checkState(existingUser.getPassword() != null, "Cannot authenticate: user with id: %s (email: %s) without password", existingUser.getId(), existingUser.getEmail()); if (isMatched(plaintextPassword, existingUser.getPassword())) { return user; } } return Optional.absent(); } }